﻿// <copyright file="KinectEventArgs.cs" company="Ucaya">
// </copyright>
// <author>Ucaya</author>

namespace KinectExtensions.Nui
{
    #region

    using System;
    using System.Windows;
    using System.Windows.Media;

    #endregion

    /// <summary>
    ///   TODO: Update summary.
    /// </summary>
    public class KinectEventArgs : EventArgs
    {
        #region Constructors and Destructors

        /// <summary>
        ///   Initializes a new instance of the <see cref = "KinectEventArgs" /> class.
        /// </summary>
        /// <param name = "position">
        ///   The position.
        /// </param>
        public KinectEventArgs(Point position)
        {
            this.Position = position;
        }

        #endregion

        #region Public Properties

        /// <summary>
        ///   If an event handler sets this to true, it stops event bubbling.
        /// </summary>
        public bool Handled { get; set; }

        /// <summary>
        ///   The first hit-testable item under the touch point. Determined by a combination of order in the tree and
        ///   Z-order.
        /// </summary>
        public object OriginalSource { get; internal set; }

        #endregion

        #region Properties

        /// <summary>
        ///   The point, in unrotated screen coordinates, where the first touchpoint is now.
        /// </summary>
        protected Point Position { get; private set; }

        #endregion

        #region Public Methods

        /// <summary>
        ///   Returns the position of the gesture's starting point relative to a given UIElement.
        /// </summary>
        /// <param name = "relativeTo">
        ///   The return value will be relative to this element.
        /// </param>
        /// <returns>
        ///   The gesture's starting point relative to the given UIElement.
        /// </returns>
        public Point GetPosition(UIElement relativeTo)
        {
            return GetPosition(relativeTo, this.Position);
        }

        #endregion

        #region Methods

        /// <summary>
        ///   Returns the position of a given point relative to a given UIElement.
        /// </summary>
        /// <param name = "relativeTo">
        ///   The return value will be relative to this element.
        /// </param>
        /// <param name = "point">
        ///   The point to translate.
        /// </param>
        /// <returns>
        ///   The given point relative to the given UIElement.
        /// </returns>
        protected static Point GetPosition(UIElement relativeTo, Point point)
        {
            if (relativeTo == null)
            {
                // Transform relative to RootVisual
                relativeTo = Application.Current.MainWindow;
            }

            if (relativeTo != null)
            {
                // Determine position
                GeneralTransform transform = relativeTo.TransformToVisual(Application.Current.MainWindow).Inverse;
                return transform.Transform(point);
            }
            else
            {
                // Unable to transform; return point as-is
                return point;
            }
        }

        #endregion
    }
}